﻿using BlindTestApplication.Model;
using BlindTestApplication.ViewModel;
using BlindTestLibrary;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Forms;
using System.Windows.Input;

namespace BlindTestApplication
{
    public class BlindTestViewModel : ViewModelBase
    {
        #region fields
        MediaElement mediaElement;

        private ICommand localCommand;
        private ICommand serverCommand;
        private ICommand parcourirCommand;
        private ICommand listenCommand;
        private ICommand nextCommand;
        private ICommand checkCommand;
        String pathDirectory = string.Empty;
        String choiseLocal = string.Empty;
        FileInfo selectedFile;
        FileInfo[] arrayFiles;
        String userSelection = string.Empty;
        private readonly ObservableCollection<SongViewModel> songs;
        private readonly ICollectionView collectionView;
        BlindTestProcessor processor = new BlindTestProcessor();
        private ChannelFactory<IRemoteService> channelFactory;
        private IRemoteService remoteService;
        private bool isServerMode;

        #endregion fields


        #region commands

        public ICommand LocalCommand
        {
            get
            {
                if (this.localCommand == null)
                    this.localCommand = new RelayCommand(() => this.DoLocalParty(), () => this.CanLocalParty());

                return this.localCommand;
            }
        }



        private void DoLocalParty()
        {
            this.ShowConfig = Visibility.Visible;
            this.ShowPlay = Visibility.Visible;
            this.SelectedTab = 1;
            this.isServerMode = false;
        }
        private bool CanLocalParty()
        {
            return true;
        }

        public ICommand ParcourirCommand
        {
            get
            {
                if (this.parcourirCommand == null)
                    this.parcourirCommand = new RelayCommand(() => this.Parcourir(), () => this.CanParcourir());

                return this.parcourirCommand;
            }
        }

        public ICommand ServerCommand
        {
            get
            {
                if (this.serverCommand == null)
                    this.serverCommand = new RelayCommand(() => this.DoServerParty(), () => this.CanServerParty());

                return this.serverCommand;
            }
        }

       

        private void DoServerParty()
        {

            this.ShowConfig = Visibility.Collapsed;
            this.ShowPlay = Visibility.Visible;
            this.SelectedTab = 2;

            this.isServerMode = true;
            channelFactory = new ChannelFactory<IRemoteService>("SI");
            channelFactory.Open();

            remoteService = channelFactory.CreateChannel();
            //récupérer la partie envoyée par le serveur
            PartyResponse party = remoteService.GetParty();
            displayFiles(party.SongTitleList);
            selectedFile = party.SelectedSong;
        }

        private bool CanServerParty()
        {
            return true;
        }


        public ICommand ListenCommand
        {
            get
            {
                if (this.listenCommand == null)
                    this.listenCommand = new RelayCommand(() => this.Listen(), () => this.CanListen());

                return this.listenCommand;
            }
        }

        public ICommand NextCommand
        {
            get
            {
                if (this.nextCommand == null)
                    this.nextCommand = new RelayCommand(() => this.Next(), () => this.CanNext());

                return this.nextCommand;
            }
        }

        public ICommand CheckCommand
        {
            get
            {
                if (this.checkCommand == null)
                    this.checkCommand = new RelayCommand(() => this.CheckSong(), () => this.CanCheckSong());

                return this.checkCommand;
            }
        }


        #endregion commands

        public BlindTestViewModel(MediaElement _mediaElem)
        {
            this.mediaElement = _mediaElem;
            this.songs = new ObservableCollection<SongViewModel>();

            // retrieve the ICollectionView associated to the ObservableCollection of SongViewMode
            this.collectionView = CollectionViewSource.GetDefaultView(this.songs);
            if (this.collectionView == null)
                throw new NullReferenceException("collectionView");

            // listen to the CurrentChanged event to be notified when the selection changes
            this.collectionView.CurrentChanged += new EventHandler(this.OnCollectionViewCurrentChanged);
        }


        private void Parcourir()
        {
            // Does stuff here to save the memo to memory;

            var dialog = new FolderBrowserDialog();
            System.Windows.Forms.DialogResult result = dialog.ShowDialog();
            pathDirectory = dialog.SelectedPath;
            this.DirectoryPath = pathDirectory;
        }

        private bool CanParcourir()
        {
            return true;
        }

        private void Listen()
        {
            this.mediaElement.LoadedBehavior = MediaState.Manual;
            if (!this.isServerMode)
            {
                selectFile();
            }

            this.mediaElement.Source = new Uri(selectedFile.FullName);
            this.mediaElement.Play();
        }

        private bool CanListen()
        {
            if (isServerMode && this.Songs.Count > 0 || !isServerMode && !string.IsNullOrEmpty(DirectoryPath))
            {
                return true;
            }
            return false;
        }


        private void Next()
        {
        }

        private bool CanNext()
        {
            return true;
        }

        private void CheckSong()
        {
            bool response;

            if (this.isServerMode)
            {
                channelFactory = new ChannelFactory<IRemoteService>("SI");
                channelFactory.Open();

                remoteService = channelFactory.CreateChannel();
                //récupérer la partie envoyée par le serveur
                response = remoteService.checkClientChoice(selectedFile.Name, SelectedSong.Title);
            }
            else
            {
                response = selectedFile.Name.Equals(SelectedSong.Title) == true;
            }

            if (response)
            {
                MyMessageBox.MyMessageBox.Show("Bravo bonne réponse! Tu auras un cadeau !");
                this.mediaElement.Stop();

                this.Songs.Clear();

            }
            else
            {
                MyMessageBox.MyMessageBox.Show("C'est pas la bonne réponse! Choisissez une autre!");
            }

       }

        private bool CanCheckSong()
        {
            if (SelectedSong != null)
            {
                return true;
            }
            return false;
        }

        private void selectFile()
        {
            PartyResponse party = processor.selectFile(DirectoryPath);
            this.selectedFile = party.SelectedSong;
            displayFiles(party.SongTitleList);
        }

        //private List<FileInfo> selectTitles()
        //{
        //    List<FileInfo> listFile = new List<FileInfo>();

        //    int nbFile = 4;

        //    Random rnd = new Random();

        //    while (listFile.Count < nbFile)
        //    {
        //        int index = rnd.Next(arrayFiles.Length);
        //        FileInfo file = arrayFiles[index];
        //        if (!listFile.Contains(file))
        //            listFile.Add(file);
        //    }

        //    return listFile;
        //}

        private void displayFiles(List<FileInfo> listFile)
        {
            this.Songs.Clear();

            foreach (FileInfo file in listFile)
            {
                this.Songs.Add(new SongViewModel(new Song(file)));
            }
        }

        //private void parsing()
        //{

        //    DirectoryInfo dir = new DirectoryInfo(DirectoryPath);
        //    arrayFiles = dir.GetFiles();
        //}




        #region properties

        private string directoryPath = string.Empty;
        public string DirectoryPath
        {
            get
            {
                return this.directoryPath;
            }
            set
            {
                this.directoryPath = value;
                OnPropertyChanged("DirectoryPath");
            }
        }

        private Visibility showConfig = Visibility.Collapsed;
        public Visibility ShowConfig
        {
            get
            {
                return showConfig;
            }

            set
            {
                showConfig = value;
                OnPropertyChanged("ShowConfig");
            }
        }

        private Visibility showPlay = Visibility.Collapsed;
        public Visibility ShowPlay
        {
            get
            {
                return showPlay;
            }

            set
            {
                showPlay = value;
                OnPropertyChanged("ShowPlay");
            }
        }

        private int selectedTab = 0;
        public int SelectedTab
        {
            get
            {
                return selectedTab;
            }
            set
            {
                selectedTab = value;
                OnPropertyChanged("SelectedTab");
            }
        }

        public ObservableCollection<SongViewModel> Songs
        {
            get { return this.songs; }
        }

        public SongViewModel SelectedSong
        {
            get { return this.collectionView.CurrentItem as SongViewModel; }
        }


        #endregion properties

        private void OnCollectionViewCurrentChanged(object sender, EventArgs e)
        {
            OnPropertyChanged("SelectedSong");
        }

    }

}
